use axum::Router;
use axum::routing::{delete, get, post, put};
use tower_http::trace::TraceLayer;
use tracing::{info, Level};
use tracing_subscriber::EnvFilter;
use dotenvy::dotenv;

mod api;
mod db;

#[tokio::main]
async fn main() {
    dotenv().ok();

    // try_from_default_env 尝试从环境变量 RUST_LOG 中读取日志配置
    let filter = EnvFilter::try_from_default_env()
        //如果环境变量不存在或格式不正确，则通过提供一个默认配置
        .unwrap_or_else(|_| {
            //启用 tower_http 包的 debug 级别日志   启用所有包的 info 级别日志
            EnvFilter::new("tower_http=debug,info")
        });

    // 使用自定义过滤器初始化 tracing
    tracing_subscriber::fmt()
        .with_env_filter(filter)
        .with_target(true)          // 显示日志来源的模块路径
        .with_thread_ids(true)      // 显示线程ID
        .with_line_number(true)     // 显示代码行号
        .with_file(true)            // 显示源文件名
        .init();

    let pool = db::establisch_connection().await;

    let app = Router::new()
        .route("/", get(root))
        .route("/api/wx_counter/login", post(api::user::login))
        .route("/api/wx_counter/counters", get(api::counter::list))
        .route("/api/wx_counter/counters", post(api::counter::add))
        .route("/api/wx_counter/counters/:id", get(api::counter::show))
        .route("/api/wx_counter/counters/:id", put(api::counter::update))
        .route("/api/wx_counter/counters/:id", delete(api::counter::destroy))
        .route("/api/wx_counter/counters_records", post(api::counter_record::add))
        .route("/api/wx_counter/counters_records/:counter_id", get(api::counter_record::list))
        .layer(
            TraceLayer::new_for_http()
                .make_span_with(tower_http::trace::DefaultMakeSpan::new().level(Level::DEBUG))
                .on_request(tower_http::trace::DefaultOnRequest::new().level(Level::DEBUG))
                .on_response(tower_http::trace::DefaultOnResponse::new().level(Level::DEBUG))
        )
        .with_state(pool);

    let listener = tokio::net::TcpListener::bind("localhost:8000").await.unwrap();
    info!("listening on http://{}", listener.local_addr().unwrap());

    axum::serve(listener, app).await.unwrap();
}


async fn root() -> &'static str {
    "Hello, world!"
}